package com.lovo.web.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lovo.commom.CscRemote.ICscUserOrderRemote;
import com.lovo.commom.CscRemote.ICscUserRemote;
import com.lovo.commom.remoteMethod.ISysUserOrderRemote;
import com.lovo.web.bean.DepositHistoryBean;
import com.lovo.web.bean.UserBean;
import com.lovo.web.bean.UserOrderBean;
import com.lovo.web.config.AlipayConfig;
import com.lovo.web.mapper.IDepositHistoryMapper;
import com.lovo.web.mapper.IUserMapper;
import com.lovo.web.qrcode.QRCodeUtil;
import com.lovo.web.qrcode.QrCodeResponse;
import com.lovo.web.qrcode.QrResponse;
import com.lovo.web.service.IAlipayService;
import com.lovo.web.service.IUserOrderService;
import com.lovo.web.util.ParamsUtil;
import com.lovo.web.vo.PayVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;


@Service
public class AlipayServiceImpl implements IAlipayService {

    Logger logger = LoggerFactory.getLogger(AlipayServiceImpl.class);
    @Autowired
    AlipayConfig alipayConfig;
    @Autowired
    IUserOrderService orderService;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    IUserMapper userMapper;
    @Autowired
    IDepositHistoryMapper depositHistoryMapper;
    @Autowired
    ISysUserOrderRemote sysUserOrderRemote;
    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    ICscUserRemote userRemote;

    @Autowired
    ICscUserOrderRemote userOrderRemote;


    @Override
    public byte[] alipay(PayVo payVo) throws Exception {
        /**
         * 1. 获取阿里客户端
         * 2. 获取阿里请求对象
         * 3. 设置请求参数
         * 4. 设置同步通知回调路径
         * 5. 设置异步通知回调路径
         */
        float payMoney = payVo.getMoney();
        DecimalFormat df = new DecimalFormat("#.00");
        JSONObject jsonObject = new JSONObject();
        if (payVo.getPayMethod() == 0) {//支付
            //通过订单编号集合得到订单信息集合
            List<UserOrderBean> orders = orderService.findByNumList(payVo.getOrderNumList());
            if (orders.size() == 0) {
                return null;
            }
            //获取支付总金额
            for (UserOrderBean o : orders) {
                payMoney += o.getBuyPrice();
            }
            //设置支付回调时可以在request中获取的参数
            jsonObject.put("key", payVo.getOrderNumList().get(0));
            jsonObject.put("nums", payVo.getOrderNumList());
        } else {//充值
            //设置支付回调时可以在request中获取的参数
            jsonObject.put("key", payVo.getBuyerName() + payVo.getTime());
            jsonObject.put("money", payVo.getMoney());
            jsonObject.put("userName", payVo.getBuyerName());
        }
        jsonObject.put("method", payVo.getPayMethod());
        String params = jsonObject.toString();
        //设置支付参数
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        model.setBody(params);
        //设置支付金额
        model.setTotalAmount(df.format(payMoney));
        //设置订单号
        model.setOutTradeNo(String.valueOf(System.currentTimeMillis()));
        //设置商品名称
        model.setSubject("lovo商城");
        //获取响应二维码信息
        QrCodeResponse qrCodeResponse = qrcodePay(model);
        //制作二维码并且返回给前端
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//        String logopath = "http://hzx.ezy2.top/zfb.jpg";
//        logopath = ResourceUtils.getFile("classpath:favicon.png").getAbsolutePath();
//        logger.info("二维码的图片路径为===>" + logopath);
//        BufferedImage encode = QRCodeUtil.encode(qrCodeResponse.getQr_code(), logopath, false);
        BufferedImage encode = QRCodeUtil.encode(qrCodeResponse.getQr_code(), null, false);
        ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(byteArrayOutputStream);
        ImageIO.write(encode, "JPEG", imageOutputStream);
        imageOutputStream.close();
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        return FileCopyUtils.copyToByteArray(byteArrayInputStream);
    }


    @Override
    public Boolean alipayCallback(HttpServletRequest request) {
        try {
            Map<String, String> params = ParamsUtil.ParamstoMap(request);
            logger.info("回调参数=========>" + params);
            String trade_no = params.get("trade_no");
            String body1 = params.get("body");
            logger.info("交易的流水号和交易信息===========>", trade_no, body1);
            JSONObject body = JSONObject.parseObject(body1);
            String key = body.getString("key");
            String method = body.getString("method");
            if (key != null) {
                LocalDate pay = LocalDate.now();
                //放入redis队列
                redisTemplate.opsForList().leftPush(key, "success");
                if ("0".equals(method)) {//支付
                    List<String> nums = JSON.parseArray(body.getString("nums"));
                    //更改订单状态(支付时间，numList)
                    orderService.updateOrderStatus(nums, pay);
                    //远程修改订单状态
                    for (String s : nums) {
                        //后端订单状态修改
                        sysUserOrderRemote.updateStatus(s, 1, pay.toString());
                        //审核订单状态修改
                        userOrderRemote.CscUpdateStatus(s, 1, pay.toString());
                    }


                } else {//充值，修改金额，添加实体
                    float money = Float.parseFloat(body.getString("money"));
                    String userName = body.getString("userName");
                    QueryWrapper<UserBean> uqw = new QueryWrapper<>();
                    uqw.eq("u_userName", userName);
                    UserBean userBean = userMapper.selectOne(uqw);
                    userBean.setMoney(userBean.getMoney() + money);
                    userMapper.updateById(userBean);
                    //远程修改用户预存款金额
                    DepositHistoryBean depositHistoryBean = new DepositHistoryBean(LocalDate.now(), money, userName);
                    depositHistoryMapper.insert(depositHistoryBean);
                    userRemote.updateMoneyByUserName(userBean.getUserName(), money);
                    //发送mq
                    rabbitTemplate.convertAndSend("depositHistoryTwoExchange", "depositHistoryTwo.key", JSON.toJSONString(depositHistoryBean));
                }

            }
        } catch (Exception e) {
            throw new RuntimeException();
//            测试日志
//            logger.info("异常====>", e.toString());
//            return false;
        }
        return true;
    }

    /**
     * 支付宝客户端发送支付请求获取支付二维码信息
     */
    public QrCodeResponse qrcodePay(AlipayTradePrecreateModel model) throws AlipayApiException {
        //1.获取请求客户端
        AlipayClient alipayClient = getAlipayClient();

        //2. 获取请求对象
        AlipayTradePrecreateRequest alipayRequest = new AlipayTradePrecreateRequest();

        //3.设置请求参数
        alipayRequest.setBizModel(model);
        //设置远程调用方法
        alipayRequest.setNotifyUrl(alipayConfig.getNotify_url());
        alipayRequest.setReturnUrl(alipayConfig.getReturn_url());
        AlipayTradePrecreateResponse execute = null;
        execute = alipayClient.execute(alipayRequest);
        String body = execute.getBody();
        logger.info("请求的响应二维码信息====>" + body);
        QrResponse qrResponse = JSON.parseObject(body, QrResponse.class);
        return qrResponse.getAlipay_trade_precreate_response();
    }

    /**
     * 获取阿里客户端
     *
     * @return
     */
    public AlipayClient getAlipayClient() {
        DefaultAlipayClient defaultAlipayClient = new DefaultAlipayClient(
                alipayConfig.getURL(),
                alipayConfig.getAPPID(),
                alipayConfig.getRSA_PRIVATE_KEY(),
                alipayConfig.getFORMAT(),
                alipayConfig.getCHARSET(),
                alipayConfig.getALIPAY_PUBLIC_KEY(),
                alipayConfig.getSIGNTYPE()
        );
        return defaultAlipayClient;
    }
}
